using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using Beetle;
using Beetle.Controller;

[AttributeUsage(AttributeTargets.Class)]
internal class h : Attribute
{
	private Dictionary<Type, u> m_a = new Dictionary<Type, u>(256);

	private u a(Type A_0)
	{
		u value = null;
		this.m_a.TryGetValue(A_0, out value);
		return value;
	}

	public void a(Assembly A_0)
	{
		Type[] types = A_0.GetTypes();
		foreach (Type a_ in types)
		{
			b(a_);
		}
	}

	public void b(Type A_0)
	{
		h[] typeAttributes = q.GetTypeAttributes<h>(A_0, inhert: false);
		if (typeAttributes.Length > 0 && !A_0.IsAbstract)
		{
			a(A_0, Activator.CreateInstance(A_0), q.GetTypeAttributes<FilterAttribute>(A_0, inhert: false));
		}
	}

	public void b(object A_0)
	{
		Type type = A_0.GetType();
		a(type, A_0, q.GetTypeAttributes<FilterAttribute>(type, inhert: false));
	}

	private List<Type> a(MethodInfo A_0)
	{
		List<Type> list = new List<Type>(8);
		SkipFilterAttribute[] methodAttributes = q.GetMethodAttributes<SkipFilterAttribute>(A_0, inhert: false);
		foreach (SkipFilterAttribute skipFilterAttribute in methodAttributes)
		{
			if (skipFilterAttribute.Types != null)
			{
				Type[] types = skipFilterAttribute.Types;
				foreach (Type item in types)
				{
					list.Add(item);
				}
			}
		}
		return list;
	}

	private void a(Type A_0, object A_1, FilterAttribute[] A_2)
	{
		MethodInfo[] methods = A_0.GetMethods(BindingFlags.Instance | BindingFlags.Public);
		foreach (MethodInfo methodInfo in methods)
		{
			ParameterInfo[] parameters = methodInfo.GetParameters();
			if (parameters.Length != 2 || !(parameters[0].ParameterType == typeof(IChannel)))
			{
				continue;
			}
			List<Type> list = a(methodInfo);
			u u2 = new u();
			u2.d = new au(methodInfo);
			u2.a = A_1;
			u2.b = q.GetMethodAttributes<UseThreadPool>(methodInfo, inhert: false).Length > 0;
			foreach (FilterAttribute filterAttribute in A_2)
			{
				if (!list.Contains(filterAttribute.GetType()))
				{
					u2.c.Add(filterAttribute);
				}
			}
			FilterAttribute[] methodAttributes = q.GetMethodAttributes<FilterAttribute>(methodInfo, inhert: false);
			foreach (FilterAttribute filterAttribute2 in methodAttributes)
			{
				if (!list.Contains(filterAttribute2.GetType()))
				{
					u2.c.Add(filterAttribute2);
				}
			}
			this.m_a[parameters[1].ParameterType] = u2;
		}
	}

	public bool Invoke(IChannel A_0, object A_1)
	{
		u u2 = a(A_1.GetType());
		if (u2 != null)
		{
			if (u2.b)
			{
				ThreadPool.QueueUserWorkItem(a, new object[3] { A_0, A_1, u2 });
			}
			else
			{
				a(new object[3] { A_0, A_1, u2 });
			}
			return true;
		}
		return false;
	}

	private void a(object A_0)
	{
		IChannel channel = null;
		object[] array = (object[])A_0;
		try
		{
			channel = (IChannel)array[0];
			u a_ = (u)array[2];
			using ActionContext actionContext = ActionContext.GetContext();
			actionContext.a(channel, array[1], a_);
			actionContext.Execute();
			if (actionContext.Result != null)
			{
				channel.Send(actionContext.Result);
			}
		}
		catch (Exception exception)
		{
			try
			{
				channel.InvokeChannelError(new ControllerError
				{
					Channel = channel,
					Exception = exception,
					Message = array[1]
				});
			}
			catch
			{
			}
		}
	}
}
